#ifndef BTREE_H_
#define BTREE_H_

#include <string>
#include <stdexcept>
#include "../BloqArch/ArchBloques.h"
#include "../BloqArch/INodo.h"
#include "../common/Resultados.h"
#include "HeaderDatos.h"
#include "NodoDatos.h"
#include "RegistroDatos.h"
#include "RegistroIndice.h"
#include "../BTreeUtils/TreePrinter.h"


class BTree {
private:
	ArchBloques _arch;
	HeaderDatos _cabecera;

	// Para permitir la lectura secuencial de los datos
	const NodoDatos* _nSecuencial;

	int guardarNodo(INodo* n, int posBloque = -1);
	INodo* cargarNodo(int posBloque, int altura);
	void actualizarCabecera(INodo* newRaiz);

	RegistroDatos buscarRecursivo(RegistroDatos regId, INodo* nodo, int altura);
	Resultado insertarRegistroRecursivo(RegistroDatos* reg, INodo* Npadre, int altura);
	Resultado resolverOverflow(INodo* nHijo, INodo* nPadre, RegistroIndice rPadre, int altura);

	// Usado para encontrar el nodo utilizado por el recorrido secuencial
	const NodoDatos* buscarNodoPorRegistro(const RegistroDatos& reg, int posNodo, int altura);

public:
	BTree();
	BTree(std::string nomArch, bool crear = false);
	virtual ~BTree();

	// Para hacer la inicialización del árbol mas tarde
	bool abrir(std::string nomArch);
	bool crear(std::string nomArch);

	// Al buscar lo hace usando el campo clave del registro
	RegistroDatos buscarRegistro(RegistroDatos regBuscar);

	// Inserta el registro en el árbol
	Resultado insertarRegistro(RegistroDatos* reg);

	// Devuelve una copia del registro de datos con menor Id del árbol
	RegistroDatos proximoRegistroPorId();

	// Devuelve una copia del proximo registro con id mayor a "regID"
	RegistroDatos proximoRegistroPorId(const RegistroDatos regID);

	// Permite imprimir el árbol
	friend class TreePrinter;
};

#endif /* BTREE_H_ */
